跳至主要内容

Dice Combinations

題目

有幾種方法可以用骰子骰出點數 nn ?

骰子只會骰出 1166 的數字。

輸入

輸入一個正整數 nn 。(1n1061 \le n \le 10^6

輸出

輸出一個正整數,為答案模 109+710^9+7 的值

範例測資

Input:
3

Output:
4
  • 1+1+11 + 1 + 1
  • 1+21 + 2
  • 2+12 + 1
  • 33

44 種方法

想法

假設要骰出數字 1818,有以下 66 種方法 :

  • 原本骰出 1212 後再骰出 66
  • 原本骰出 1313 後再骰出 55
  • 原本骰出 1414 後再骰出 44
  • 原本骰出 1515 後再骰出 33
  • 原本骰出 1616 後再骰出 22
  • 原本骰出 1717 後再骰出 11

狀態定義

dpidp_{i} 為湊出點數為 ii 的方法數。

狀態轉移

藉由上面的例子,我們可以得知 dpi=dpi1+dpi2+dpi3+dpi4+dpi5+dpi6dp_{i} = dp_{i - 1} + dp_{i - 2} + dp_{i - 3} + dp_{i - 4} + dp_{i - 5} + dp_{i - 6}

Note 1 : dp0=1dp_{0} = 1,因為只有一種方法可以湊出點數 00 (也就是沒有骰骰子)

Note 2: i=5i = 5 以前的 dpidp_{i} 都要注意,轉移狀態時不能讓 j<0j < 0

範例程式碼

C++ 範例
#include <bits/stdc++.h>
#define int long long
#define IO ios_base::sync_with_stdio(0), cin.tie(0)
using namespace std;
const int mod = 1e9 + 7, sz = 1e6 + 5;
int n, dp[sz];

signed main() {
IO;
cin >> n;
dp[0] = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= 6; j++) {
if(i - j >= 0) {
dp[i] += dp[i - j];
dp[i] %= mod;
}
}
}
cout << dp[n];
}